from typing import Dict


def new_board() -> Dict[int, str]:
    """
    Using a dictionary in python to store the board,
    since we are not including all numbers within a given range.
    """
    return {
        13: "!",
        14: "!",
        15: "!",
        22: "!",
        23: "!",
        24: "!",
        29: "!",
        30: "!",
        31: "!",
        32: "!",
        33: "!",
        34: "!",
        35: "!",
        38: "!",
        39: "!",
        40: "!",
        42: "!",
        43: "!",
        44: "!",
        47: "!",
        48: "!",
        49: "!",
        50: "!",
        51: "!",
        52: "!",
        53: "!",
        58: "!",
        59: "!",
        60: "!",
        67: "!",
        68: "!",
        69: "!",
        41: "O",
    }


def print_instructions() -> None:
    print(
        """
HERE IS THE BOARD:

          !    !    !
         13   14   15

          !    !    !
         22   23   24

!    !    !    !    !    !    !
29   30   31   32   33   34   35

!    !    !    !    !    !    !
38   39   40   41   42   43   44

!    !    !    !    !    !    !
47   48   49   50   51   52   53

          !    !    !
         58   59   60

          !    !    !
         67   68   69

TO SAVE TYPING TIME, A COMPRESSED VERSION OF THE GAME BOARD
WILL BE USED DURING PLAY.  REFER TO THE ABOVE ONE FOR PEG
NUMBERS.  OK, LET'S BEGIN.
    """
    )


def print_board(board: Dict[int, str]) -> None:
    """Prints the boards using indexes in the passed parameter"""
    print(" " * 2 + board[13] + board[14] + board[15])
    print(" " * 2 + board[22] + board[23] + board[24])
    print(
        board[29]
        + board[30]
        + board[31]
        + board[32]
        + board[33]
        + board[34]
        + board[35]
    )
    print(
        board[38]
        + board[39]
        + board[40]
        + board[41]
        + board[42]
        + board[43]
        + board[44]
    )
    print(
        board[47]
        + board[48]
        + board[49]
        + board[50]
        + board[51]
        + board[52]
        + board[53]
    )
    print(" " * 2 + board[58] + board[59] + board[60])
    print(" " * 2 + board[67] + board[68] + board[69])


def play_game() -> None:
    # Create new board
    board = new_board()

    # Main game loop
    while not is_game_finished(board):
        print_board(board)
        while not move(board):
            print("ILLEGAL MOVE! TRY AGAIN")

    peg_count = sum(1 for key in board.keys() if board[key] == "!")
    print(f"YOU HAD {str(peg_count)} PEGS REMAINING")

    if peg_count == 1:
        print("BRAVO! YOU MADE A PERFECT SCORE!")
        print("SAVE THIS PAPER AS A RECORD OF YOUR ACCOMPLISHMENT!")


def move(board: Dict[int, str]) -> bool:
    """Queries the user to move. Returns false if the user puts in an invalid input or move, returns true if the move was successful"""
    #要求用户输入起始跳动的棋子位置
    start_int = input("Enter the starting position of the jumping piece")
    #如果输入的数据不是数字，return false
    if not start_int.isdigit():
        return False
    #把用户输入转换数字
    else:
        start = int(start_int)
    #如果起始位置不在棋盘上或者起始位置不是！（棋子） 返回false
    if start not in board or board[start] != "!":
        return False
    #要求用户输入一个结束位置
    end_int = input("Enter the ending position of the jumping piece")
    #如果用户输入的数据不是数字，返回false
    if not end_int.isdigit():
        return False
    #把用户输入的内容转数字
    else:
        end = int(end_int)

    #如果如果结束位置不在棋盘上或者结束位置不是0（空缺） 返回false
    if end not in board or board[end] != "O":
        return False
    #找到中间的棋子在字典里面的位置并且将其替换为0
    difference = abs(start-end)
    center = int((end+start)/2)
    print("--------------------------------------")
    if difference in [2, 18] and board[center] == "!":
        board[start] = "O"
        board[center] = "O"
        board[end] = "!"
        return True

def main() -> None:
    print(" " * 33 + "H-I-Q")
    print(" " * 15 + "CREATIVE COMPUTING  MORRISTOWN, NEW JERSEY")
    print_instructions()
    play_game()


def is_game_finished(board) -> bool:
    """Check all locations and whether or not a move is possible at that location."""
    for pos in board.keys():
        if board[pos] == "!":
            for space in [1, 9]:
                # Checks if the next location has a peg
                next_to_peg = ((pos + space) in board) and board[pos + space] == "!"
                # Checks both going forward (+ location) or backwards (-location)
                has_movable_space = (
                        pos - space not in board
                        or board[pos - space] != "!"
                        or pos + space * 2 not in board
                        or board[pos + space * 2] != "!"
                )
                if next_to_peg and has_movable_space:
                    return False
    return True


if __name__ == "__main__":
    main()